package cz.muni.fi.pa165.soccergamesarchive.persistencelayer.entities;

import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;

/**
 *
 * @author Martin Fabian
 *
 * <strong>Remake by Michal Ďuriš</strong>
 */
@Entity
@NamedQueries({
    @NamedQuery(name = "Team.getAllTeams", query = "SELECT t FROM Team t"),
    @NamedQuery(name = "Team.findTeam",
                query = "SELECT t "
                + "FROM Team t "
                + "WHERE LOWER(t.name) LIKE :searchString "),
    @NamedQuery(name = "Team.getStatistics",
                query = "SELECT (SELECT COUNT(m) "
                + "FROM SoccerMatch m "
                + "WHERE (t.id = m.homeTeam.id OR t.id = m.awayTeam.id) "
                + "AND (SELECT COUNT(g) "
                + "FROM Goal g "
                + "WHERE g.soccerMatch.id = m.id "
                + "AND g.player.team.id = t.id ) "
                + "> "
                + "(SELECT COUNT(g) "
                + "FROM Goal g "
                + "WHERE g.soccerMatch.id = m.id "
                + "AND g.player.team.id != t.id )), "
                + "(SELECT COUNT(m) "
                + "FROM SoccerMatch m "
                + "WHERE (t.id = m.homeTeam.id OR t.id = m.awayTeam.id) "
                + "AND (SELECT COUNT(g) "
                + "FROM Goal g "
                + "WHERE g.soccerMatch.id = m.id "
                + "AND g.player.team.id = t.id ) "
                + "= "
                + "(SELECT COUNT(g) "
                + "FROM Goal g "
                + "WHERE g.soccerMatch.id = m.id "
                + "AND g.player.team.id != t.id )), "
                + "(SELECT COUNT(m) "
                + "FROM SoccerMatch m "
                + "WHERE (t.id = m.homeTeam.id OR t.id = m.awayTeam.id) "
                + "AND (SELECT COUNT(g) "
                + "FROM Goal g "
                + "WHERE g.soccerMatch.id = m.id "
                + "AND g.player.team.id = t.id ) "
                + "< "
                + "(SELECT COUNT(g) "
                + "FROM Goal g "
                + "WHERE g.soccerMatch.id = m.id "
                + "AND g.player.team.id != t.id )), "
                + "(SELECT COUNT(g) "
                + "FROM Goal g "
                + "WHERE g.player.team.id = t.id), "
                + "(SELECT COUNT(g) "
                + "FROM Goal g, SoccerMatch m "
                + "WHERE (t.id = m.homeTeam.id OR t.id = m.awayTeam.id) "
                + " AND g.soccerMatch.id = m.id "
                + " AND g.player.team.id != t.id) "
                + "FROM Team t "
                + "WHERE t.id = :teamID "),
    @NamedQuery(name = "Team.getOccupiedShirtNumbers",
                query = "SELECT p.shirtNumber "
                + "FROM Team t, Player p "
                + "WHERE t.id = :teamID "
                + "AND t.id = p.team.id ")
})
public class Team implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(length = 40, nullable = false)
    private String name;

    @Column(length = 40, nullable = false)
    private String managerName;

    @OneToMany(mappedBy = "team", orphanRemoval = true,
               cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private List<Player> players;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getManagerName() {
        return managerName;
    }

    public void setManagerName(String managerName) {
        this.managerName = managerName;
    }

    public List<Player> getPlayers() {
        return players;
    }

    public void setPlayers(List<Player> players) {
        this.players = players;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Team other = (Team) obj;
        if (!Objects.equals(this.id, other.id)) {
            return false;
        }
        if (!Objects.equals(this.name, other.name)) {
            return false;
        }

        return Objects.equals(this.managerName, other.managerName);
    }

    @Override
    public String toString() {
        return "Team{" + "id=" + id + ", name=" + name + ", managerName="
                + managerName + '}';
    }

}
